/*
 * 青莲客户端 处理 
 *
 *
 *
 */

#include <stdio.h>
#include "charge.h"
#include "qlcloud_client.h"
#include "ql_main_interface.h"
#include "charge_user.h"
#include "app_debug_ql.h"
#include "protocol_offset.h"

typedef struct {
	int  offset_yx;
	int  errCode;
}YXIndexToErrCode_t;

typedef struct
{
    int errReason;
    int errCode;
}failureReasonCode_t;

char _tmp_print_str[128];

// 遥信值（can口传递过来的） 
out_yx yxdata[CHARGE_GUN_CNT];

// 遥测值（can口传递过来的） 
union u_out_mx ycdata[CHARGE_GUN_CNT];

// 启动充电信息 
start_mx g_startInfo[CHARGE_GUN_CNT];

// 充电参数 
Charge_Arg g_chargepara_ql[CHARGE_GUN_CNT];

// 停止充电信息 
end_mx g_stopInfo[CHARGE_GUN_CNT];

// 电表实时数据 
MeterDataReal g_realmtData[CHARGE_GUN_CNT+1];

// 读取的最后充电功率 
u32 last_kWh[]={0,0,0,0,0,0,0,0};

// can通讯是否正常 
int g_can_state[CHARGE_GUN_CNT];

// 设备充电状态 
int g_charge_state[]={NO_CHARGING,NO_CHARGING,NO_CHARGING,NO_CHARGING,NO_CHARGING,NO_CHARGING,NO_CHARGING,NO_CHARGING};

MeterData_ql g_mtData[CHARGE_GUN_CNT];

// 设备充电停电操作结果
int update_operate_result[8] = {0};

// 设备操作结果标志及原因
u16  charge_operate_result[8][2] = {0};

// dc yx22
YXIndexToErrCode_t yx22_err_code[] =
{
    {DC_IND_EMERSTOP_FAULT_OFFSET, DEV_ERR_3003},
    {DC_IND_AC_BREAKER_OFFSET, POWER_ERR_4005},
    {DC_IND_DC_OUT_CONTACTOR_OFFSET, DEV_ERR_3010},
    {DC_IND_DC_OUT_FUSES_OFFSET, DEV_ERR_3011},
    {DC_IND_INTERFACE_ELE_LOCK_FAULT_OFFSET, DEV_ERR_3018},
    {DC_IND_CHARGE_FAN_OFFSET, DEV_ERR_3004},
	{DC_IND_THUNDERBOLT_OFFSET, POWER_ERR_400C},//20210624 add by cz
    {DC_IND_INSULATION_OFFSET, DEV_ERR_3014},
    {DC_IND_BATTERY_REVERSE_OFFSET, CAR_ERR_501A},
    {DC_IND_PILE_OVERTURNED_OFFSET, DEV_ERR_3016},
    {DC_IND_GUNS_OVERTURNED_OFFSET, DEV_ERR_3017},
    {DC_IND_GUNS_NO_HOMELESS_OFFSET, DEV_ERR_3006},
    {DC_IND_BMS_COMMUNICATION_OFFSET, CAR_ERR_5000},
    {DC_IND_INPUT_V_OVER_OFFSET, POWER_ERR_4000},
    {DC_IND_INPUT_V_UNDER_OFFSET, POWER_ERR_4000},
    {DC_IND_DC_BUS_OUT_V_OVER_OFFSET, POWER_ERR_4001},
    {DC_IND_DC_BUS_OUT_V_UNDER_OFFSET, POWER_ERR_4003},
    {DC_IND_DC_BUS_OUT_A_OVER_OFFSET, POWER_ERR_4002},
    {DC_IND_CHARGE_MODULE_OFFSET, DEV_ERR_300A},
    {DC_IND_MODULE_AC_INPUT_OFFSET, POWER_ERR_4000},
    {DC_IND_MODULE_AC_IN_V_OVER_OFFSET, POWER_ERR_4000},
    {DC_IND_MODULE_AC_IN_V_UNDER_OFFSET, POWER_ERR_4000},
    {DC_IND_MODULE_AC_IN_PHASE_OFFSET, POWER_ERR_4009},
    {DC_IND_MODULE_DC_OUT_SHORT_OFFSET, POWER_ERR_4004},
    {DC_IND_MODULE_DC_OUT_A_OVER_OFFSET, POWER_ERR_4002},
    {DC_IND_MODULE_DC_OUT_V_OVER_OFFSET, POWER_ERR_4001},
    {DC_IND_MODULE_DC_OUT_V_UNDER_OFFSET, POWER_ERR_4003},
    {DC_IND_MODULE_OVERTURNED_OFFSET, POWER_ERR_400D},
	{DC_IND_MODULE_OVERTURNED_OFFSET, DEV_ERR_300B},
    {DC_IND_MODULE_COMMUNICATION_OFFSET, DEV_ERR_3008},
    {DC_IND_MODULE_FAN_OFFSET, DEV_ERR_3005},
} ;

YXIndexToErrCode_t yx23_err_code[] =
{
	{DC_IND_DOOR_FAULT_OFFSET, DEV_ERR_3002},
	{DC_IND_DC_BUS_OUT_CONTACTOR_ADHESION_FAULT_OFFSET, DEV_ERR_300F},
	{DC_IND_INSULATION_WARN_OFFSET, DEV_ERR_3014},
	{DC_IND_DISCHARGE_LOOP_WARN_OFFSET, DEV_ERR_3015},
	{DC_IND_CHARGE_PILE_OVERTURNED_WARN_OFFSET, DEV_ERR_3016},
	{DC_IND_CHARGE_GUN_OVERTURNED_WARN_OFFSET, DEV_ERR_3017},
	{DC_IND_AC_IN_CONTACTOR_ERR_ACTION_OFFSET, DEV_ERR_302A},
	{DC_IND_AC_IN_CONTACTOR_ADHESION_FAULT_OFFSET, DEV_ERR_302A},
	{DC_IND_ASSIST_POWER_FAULT_OFFSET, DEV_ERR_3013},
	{DC_IND_PARALLEL_CONTACTOR_ERR_ACTION_OFFSET, DEV_ERR_3010},
	{DC_IND_PARALLEL_CONTACTOR_ADHESION_FAULT_OFFSET, DEV_ERR_302D},
	{DC_IND_MODULE_EMERGENCY_STOP_OFFSET, DEV_ERR_3003},
//	{DC_IND_DEVICE_FLOODING_FAULT_OFFSET, DEV_ERR_301D},
//	{DC_IND_BOX_ACCESS_FAULT_OFFSET, DEV_ERR_301D},
	{DC_IND_MODULE_FLOODING_FAULT_OFFSET, POWER_ERR_400D},
	{DC_IND_MODULE_SMOKING_FAULT_OFFSET, POWER_ERR_400D},
	{DC_IND_POWER_CTRL_MODULE_COMM_FAULT_OFFSET, DEV_ERR_3044},
	{DC_IND_POWER_CTRL_MODULE_COMM_WARN_OFFSET, DEV_ERR_3044},
	{DC_IND_POWER_CTRL_MODULE_FAULT_OFFSET, DEV_ERR_3044},
	{DC_IND_POWER_CTRL_MODULE_WARN_OFFSET, DEV_ERR_3044},
//	{DC_IND_POWER_CTRL_MODULE_COMM_FAULT_OFFSET, POWER_ERR_400D},
//	{DC_IND_POWER_CTRL_MODULE_COMM_WARN_OFFSET, POWER_ERR_400D},
//	{DC_IND_POWER_CTRL_MODULE_FAULT_OFFSET, POWER_ERR_400D},
//	{DC_IND_POWER_CTRL_MODULE_WARN_OFFSET, POWER_ERR_400D},
	{DC_IND_CONTROLER_BMS_FAULT_OFFSET, CAR_ERR_5011},
	{DC_IND_BMS_SEND_FAULT_OFFSET, CAR_ERR_5011},
	{DC_IND_MODULE_LOOP_FAULT_OFFSET, DEV_ERR_3015},
	{DC_IND_INSULATION_DEVICE_COMM_FAULT_OFFSET, DEV_ERR_3037},
	{DC_IND_ENVI_MONITOR_COMM_FAULT_OFFSET, DEV_ERR_3033},
	{DC_IND_LAMP_COMM_FAULT_OFFSET, DEV_ERR_303A},
	{DC_IND_METER_COMM_FAULT_OFFSET, DEV_ERR_300D}

};

// 启动充电失败原因
failureReasonCode_t start_charge_reason_map[] =
{
    {0x01, CHARGE_STOP_GUN_CONN_ERR},   // 充电中控制导引故障
    {0x02, DEV_ERR_3032},   // 计费控制单元通讯故障
    {0x03, DEV_ERR_3003},   // 急停按钮动作故障
    {0x04, DEV_ERR_3002},   // 门禁故障（充电桩）
    {0x05, POWER_ERR_400C}, // 避雷器故障
    {0x06, DEV_ERR_3033},   // 烟感故障
    {0x07, POWER_ERR_4005}, // 交流输入断路器故障
    {0x08, DEV_ERR_302A},   // 交流输入接触器拒动/误动故障
    {0x09, DEV_ERR_301D},   // 交流输入接触器粘连故障
    {0x0A, POWER_ERR_4000}, // 交流输入故障（过压，欠压，缺相，过流）
    {0x0B, DEV_ERR_3016},   // 充电桩过温故障
    {0x0C, DEV_ERR_3017},   // 充电接口过温故障
    {0x0D, DEV_ERR_3018},   // 充电接口电子锁故障
    {0x0E, DEV_ERR_3014},   // 绝缘监测故障
    {0x0F, CAR_ERR_501A},   // 电池极性反接故障
    {0x10, DEV_ERR_3010},   // 直流输出接触器拒动/误动故障
    {0x11, DEV_ERR_300F},   // 直流输出接触器粘连故障
    {0x12, DEV_ERR_3011},   // 直流输出熔断器故障
    {0x13, DEV_ERR_300F},   // 并联接触器拒动/误动故障
    {0x14, DEV_ERR_302D},   // 并联接触器粘连故障
    {0x15, DEV_ERR_3015},   // 泄放回路故障
    {0x16, DEV_ERR_3013},   // 辅助电源故障
    {0x17, DEV_ERR_300A},   // 充电机模块故障
    {0x18, POWER_ERR_4001}, // 直流母线输出电压过压故障
    {0x19, POWER_ERR_4003}, // 直流母线输出电压欠压故障
    {0x1A, POWER_ERR_4002}, // 直流母线输出电流过流故障
    {0x1B, POWER_ERR_4004}, // 直流母线输出短路故障
    {0x1C, CAR_ERR_503C},   // 电池最高允许充电电压小于充电机最小输出电压
    {0x1D, POWER_ERR_4006},   // 绝缘监测前直流输出接触器外侧电压≥10 V
    {0x1E, CAR_ERR_502C},   // 启动充电前直流输出接触器外侧电压与通信报文电池电压相差＞±5%
    {0x1F, CAR_ERR_500C},   // 启动充电前直流输出接触器外侧电压小于充电机最小输出电压
    {0x20, CAR_ERR_500C},   // 启动充电前直流输出接触器外侧电压大于充电机最大输出电压
    {0x21, CAR_ERR_503F},   // 电池端电压大于电池最高允许充电电压
    {0x22, CAR_ERR_500A},   // BRM 报文接收超时
    {0x23, CAR_ERR_5040},   // BRM 报文数据项异常
    {0x24, CAR_ERR_5001},   // BCP 报文接收超时
    {0x25, CAR_ERR_5041},   // BCP 报文数据项异常（报文数据长度错误，电池当前电压越限，其他数据项错误）
    {0x26, CAR_ERR_5042},   // BRO 报文（0x00）接收超时
    {0x27, CAR_ERR_5043},   // BRO 报文（0xAA）接收超时

    {0x29, CAR_ERR_5004},   // BCL报文接收超时
    {0x2A, CAR_ERR_5003},   // BCS报文接收超时
    {0x2B, DEV_ERR_3002},   // 门禁故障（充电机柜，仅直流桩使用）
    {0x2C, DEV_ERR_301D},   // 水浸故障（充电桩）
    {0x2D, DEV_ERR_301D},   // 水浸故障（充电机柜，仅直流桩使用）
    {0x2E, DEV_ERR_3044},   // 直流充电主控模块与功率控制模块通信超时（仅直流桩使用）
    {0x2F, DEV_ERR_3022},   // 功率控制模块与开关模块通信超时（仅直流桩使用）
    {0x30, DEV_ERR_3022},   // 开关模块故障（仅直流桩使用）
    {0x31, CAR_ERR_5011},   // BMS通信协议版本不匹配
    {0x32, DEV_ERR_3037},   // 绝缘监测仪通信故障
    {0x33, DEV_ERR_3000},   // 设备自检超时
    {0x34, DEV_ERR_302C},   // 预充功率分配超时
    {0x35, DEV_ERR_302E},   // 预充阶段调压失败
    {0x36, DEV_ERR_302F},   // 启动充电超时(收到启动命令开始120秒未进入充电阶段)
    {0x37, DEV_ERR_3031},   // 充电模块开机超时(下发开机命令10S不能到达绝缘监测电压)
    {0x38, DEV_ERR_3033},   // 环境监控板通信故障
    {0x39, DEV_ERR_302C},   // 自检功率分配超时

    {0x3A, DEV_ERR_303A},   // 灯板通信故障
    {0x3B, DEV_ERR_3014},   // 绝缘监测超时
    {0x3C, DEV_ERR_300D},   // 电能表通信故障
    {0x3D, CAR_ERR_500A},   // 车辆验证确认帧超时
    {0x3F, CAR_ERR_5011},   // 车辆鉴权不通过

    {0xF0, CHARGE_STATE_ERR},   //设备正在充电 
    {0xF1, CHARGE_STOP_GUN_CONN_ERR},   // 枪连接故障 
	{0xF2, DEV_ERR_3029},		// 装置未就绪，暂停使用
    {0xFF, POWER_ERR_400D},   // 充电机其他故障
};

// 停止充电失败原因
#if 0
failureReasonCode_t stop_charge_reason_map[] =
{
    {0x01, 0x1001},   // 计费控制单元正常停止
    {0x02, 0x301D},   // 计费控制单元自身故障终止
    {0x03, 0x400D},   // 计费控制单元判断充电控制器故障停止
    {0x04, 0x3030},   // 启动完成状态帧确认超时故障终止
    {0x05, 0x3039},   // 充电中控制导引故障
    {0x06, 0x3032},   // 充电控制器与计费控制单元通讯超时
    {0x07, 0x301D},   // 充电桩充电中暂停超时
    {0x08, 0x3003},   // 急停按钮动作故障
    {0x09, 0x3002},   // 门禁故障(充电桩)
    {0x0A, 0x400C},   // 避雷器故障
    {0x0B, 0x3033},   // 烟感故障
    {0x0C, 0x4005},   // 交流输入断路器故障
    {0x0D, 0x302A},   // 交流输入接触器拒动/误动故障
    {0x0E, 0x301D},   // 交流输入接触器粘连故障
    {0x0F, 0x4000},   // 交流输入故障（过压，欠压，缺相，过流）
    {0x10, 0x3016},   // 充电桩过温故障
    {0x11, 0x3017},   // 充电接口过温故障
    {0x12, 0x3018},   // 充电接口电子锁故障
    {0x13, 0x3010},   // 直流输出接触器拒动/误动故障
    {0x14, 0x300F},   // 直流输出接触器粘连故障
    {0x15, 0x3011},   // 直流输出熔断器故障
    {0x16, 0x302A},   // 并联接触器拒动/误动故障
    {0x17, 0x302D},   // 并联接触器粘连故障
    {0x18, 0x3015},   // 泄放回路故障
    {0x19, 0x3013},   // 辅助电源故障
    {0x1A, 0x300A},   // 充电机模块故障
    {0x1B, 0x4001},   // 直流母线输出电压过压故障
    {0x1C, 0x4003},   // 直流母线输出电压欠压故障
    {0x1D, 0x4002},   // 直流母线输出电流过流故障
    {0x1E, 0x4004},   // 直流母线输出短路故障
    {0x1F, 0x5004},   // BCL报文接收超时
    {0x20, 0x5003},   // BCS报文接收超时
    {0x21, 0x5007},   // 动力蓄电池状态信息（BSM）超时
    {0x22, 0x5012},   // 报文中单体动力蓄电池电压过压
    {0x23, 0x5013},   // 报文中单体动力蓄电池电压过低
    {0x24, 0x5014},   // 报文中SOC 过高
    {0x25, 0x5015},   // BSM 报文中SOC 过低
    {0x26, 0x5016},   // BSM 报文中充电过电流
    {0x27, 0x5017},   // BSM 报文中动力蓄电池温度过高
    {0x28, 0x5018},   // BSM 报文中动力蓄电池绝缘状态异常
    {0x29, 0x5019},   // BSM 报文中连接器连接状态异常
    {0x2A, 0x100B},   // BMS 正常终止充电 CAR_ERR_5011 CHARGE_STOP_BMS_CONDITION
    {0x2B, 0x100A},   // BMS 异常终止充电   CAR_ERR_5008
    {0x2C, 0x5011},   // 充电桩判断BMS 其他异常终止
    {0x2E, 0x5021},   // 无有效电流停止
    {0x2F, 0x3033},   // 环境监控板通信故障
    {0x30, 0x303A},   // 灯板通信故障
    {0x31, 0x300D},   // 电能表通信故障
    {0xFF, 0x400D},   // 充电机其他故障
};

#else 
failureReasonCode_t stop_charge_reason_map[] =
{
    {0x01, CHARGE_STOP_APP}, // 计费控制单元正常停止
    {0x02, DEV_ERR_301D},   // 计费控制单元自身故障终止
    {0x03, POWER_ERR_400D}, // 计费控制单元判断充电控制器故障停止
    {0x04, DEV_ERR_3030},   // 启动完成状态帧确认超时故障终止
    {0x05, CHARGE_STOP_GUN_CONN_ERR},   // 充电中控制导引故障
    {0x06, DEV_ERR_3032},   // 充电控制器与计费控制单元通讯超时
    {0x07, CAR_ERR_502A},   // 充电桩充电中暂停超时
    {0x08, DEV_ERR_3003},   // 急停按钮动作故障
    {0x09, DEV_ERR_3002},   // 门禁故障(充电桩)
    {0x0A, POWER_ERR_400C},   // 避雷器故障
    {0x0B, DEV_ERR_3033},   // 烟感故障
    {0x0C, POWER_ERR_4005}, // 交流输入断路器故障
    {0x0D, DEV_ERR_302A}, // 交流输入接触器拒动/误动故障
    {0x0E, DEV_ERR_301D},   // 交流输入接触器粘连故障
    {0x0F, POWER_ERR_4000}, // 交流输入故障（过压，欠压，缺相，过流）
    {0x10, DEV_ERR_3016},   // 充电桩过温故障
    {0x11, DEV_ERR_3017},   // 充电接口过温故障
    {0x12, DEV_ERR_3018},   // 充电接口电子锁故障
    {0x13, DEV_ERR_3010},   // 直流输出接触器拒动/误动故障
    {0x14, DEV_ERR_3010},   // 直流输出接触器粘连故障
    {0x15, DEV_ERR_3011},   // 直流输出熔断器故障
    {0x16, DEV_ERR_300F},   // 并联接触器拒动/误动故障
    {0x17, DEV_ERR_302D},   // 并联接触器粘连故障
    {0x18, DEV_ERR_3015},   // 泄放回路故障
    {0x19, DEV_ERR_3013},   // 辅助电源故障
    {0x1A, DEV_ERR_300A},   // 充电机模块故障
    {0x1B, POWER_ERR_4001},   // 直流母线输出电压过压故障
    {0x1C, POWER_ERR_4003},   // 直流母线输出电压欠压故障
    {0x1D, POWER_ERR_4002},   // 直流母线输出电流过流故障
    {0x1E, POWER_ERR_4004},   // 直流母线输出短路故障
    {0x1F, CAR_ERR_5004},   // BCL报文接收超时
    {0x20, CAR_ERR_5003},   // BCS报文接收超时
    {0x21, CAR_ERR_5007},   // 动力蓄电池状态信息（BSM）超时
    {0x22, CAR_ERR_5012},   // 报文中单体动力蓄电池电压过压
    {0x23, CAR_ERR_5013},   // 报文中单体动力蓄电池电压过低
    {0x24, CAR_ERR_5014},   // 报文中SOC 过高
    {0x25, CAR_ERR_5015},   // BSM 报文中SOC 过低
    {0x26, CAR_ERR_5016},   // BSM 报文中充电过电流
    {0x27, CAR_ERR_5017},   // BSM 报文中动力蓄电池温度过高
    {0x28, CAR_ERR_5018},   // BSM 报文中动力蓄电池绝缘状态异常
    {0x29, CAR_ERR_5019},   // BSM 报文中连接器连接状态异常
    {0x2A, CHARGE_STOP_FULL   },// BMS 正常终止充电 CAR_ERR_5011 CHARGE_STOP_BMS_CONDITION
    {0x2B, CHARGE_STOP_BMS_ERR},   // BMS 异常终止充电   CAR_ERR_5008
    {0x2C, CAR_ERR_5011},   // 充电桩判断BMS 其他异常终止
    {0x2E, CAR_ERR_5021},   // 无有效电流停止
    {0x2F, DEV_ERR_3033},   // 环境监控板通信故障
    {0x30, DEV_ERR_303A},   // 灯板通信故障
    {0x31, DEV_ERR_300D},   // 电能表通信故障
    {0x32, DEV_ERR_3037},   // 绝缘采样盒通讯故障 
    {0xF2, DEV_ERR_3029},	// 装置掉电，暂停使用
    {0xFF, POWER_ERR_400D}, // 充电机其他故障
};
#endif

//CCU上传的遥信报文 22 解析
u8 ql_memcmpyx_dc_22(u8 gunid,unsigned char *plast_pf22,unsigned char *pnew_pf22)
{
 	u8 tabid;
 	u8 offset;
 	u8 b1,b2;
    u8 num;
    int i;
    u8 flag_err=0;
    static u8 init_flag[8] = {0};
    static u8 emerrgency_cnt[8] = {0};
    u16 err_code = 0;

 	// 1.连接汽车状态
 	tabid = u8(DC_IND_CONNECT_CAR_OFFSET/8+1);
 	offset = DC_IND_CONNECT_CAR_OFFSET%8;
 	b1 = (plast_pf22[tabid]>>offset)&0x01;//连接汽车状态
 	b2 = (pnew_pf22[tabid]>>offset)&0x01;
    // 2.work status
 	// work_st = pnew_pf22[0] & 0x3;
 	if ((b1 != b2) || (init_flag[gunid] == 0))
 	{
		if (b2 == 1) // not link
		{
			// charge_set_gun_state(gunid + 1, GUN_STATE_IDLE);
            charge_pull_gun(gunid + 1);  // 处理拔枪事件 
		}
		else  // link car
		{
             charge_set_gun_state(gunid + 1, GUN_STATE_READY);
		}
        
    	debug_mdata1("1连接汽车状态--变化  变化前=%d  变化后=%d   gunid=%d",b1,b2,gunid);

     	debug_mdata1("1连接汽车状态--变化  变化前=%d  变化后=%d",b1,b2);
 	}

    //1 电子锁状态
 	tabid  = DC_IND_ELE_LOCK_STATUS_OFFSET/8+1;
 	offset = DC_IND_ELE_LOCK_STATUS_OFFSET%8;

 	b2 = (pnew_pf22[tabid]>>offset)&0x01;
    if (b2 > 0)
    {

        user_update_lock(gunid + 1, LOCK_STATE_FALL);
    }
    else
    {
        user_update_lock(gunid + 1, LOCK_STATE_RISE);
    }

    // 2 急停按钮
	tabid = (DC_IND_EMERSTOP_FAULT_OFFSET >> 3) + 1;
	offset = DC_IND_EMERSTOP_FAULT_OFFSET & 0x07;
	b2 = (pnew_pf22[tabid]>>offset)&0x01;
	if (b2)
	{
		charge_press_emerg_btn(gunid + 1);
	}
	//20210619 add by cz
	// 3 总故障 总告警
	tabid = (DC_IND_TOTAL_FAULT_OFFSET >> 3) + 1;
	offset = DC_IND_TOTAL_FAULT_OFFSET & 0x07;
	b2 = (pnew_pf22[tabid]>>offset)&0x03;
	b1 = (plast_pf22[tabid]>>offset)&0x03;
	if ((b2 == 0) && ((b1 != 0) || (init_flag[gunid] == 0)))
	{
		charge_fault_recover(gunid + 1);    // 系统所有告警、故障消失，系统恢复正常 
		                                    // 系统初始化后，一切正常，上报系统恢复正常，用户消除一些告警 （后续修改为保存到文件内）
	}

    init_flag[gunid] = 1;
    
    debug_mdata1("222上次上报后摇信变化pf22  %.*a  %.*a",8,plast_pf22, 8,pnew_pf22);
    num = ARRAY_LEN(yx22_err_code);
   	for (i = 0; i < num; i++)
   	{
   		tabid  = yx22_err_code[i].offset_yx / 8 + 1;
   		offset = yx22_err_code[i].offset_yx % 8;
   		b1 = (plast_pf22[tabid] >> offset) & 0x01;
   		b2 = (pnew_pf22[tabid]  >> offset) & 0x01;

		if (b1 != b2) 
		{
			if (b2 == 1)
			{
				debug_mdata("\r\n111发生故障 i:%d idx:%d errcode:0x%x", i, yx22_err_code[i].offset_yx, yx22_err_code[i].errCode);
                err_code = yx22_err_code[i].errCode;
                if ((err_code >= 0x3000) && (err_code < 0x5000))
                {
                    // 桩故障，等待修复 
                	charge_fault_upload(gunid + 1, err_code);
                }
				else if ((err_code >= 0x5000) && (err_code < 0x6000))
				{
                    // 车辆故障 只上报故设置故障 
					charge_fault_upload(gunid + 1, err_code);
                }
			}
		}
	}

	return flag_err;
}
//CCU上传的遥信报文 23 解析
 u8 ql_memcmpyx_dc_23(u8 gunid,unsigned char *plast_pf23,unsigned char *pnew_pf23)
 {
     u8 tabid;
     u8 offset;
     u8 b1,b2;
     u8 num;
     int i;
     u8 flag_err=0;
     u16 err_code = 0;
     
     debug_mdata1("222上次上报后摇信变化pf23  %.*a  %.*a",8,plast_pf23, 8,pnew_pf23);

     num = ARRAY_LEN(yx23_err_code);
	  for (i = 0; i < num; i++)
	  {
		  tabid  = yx23_err_code[i].offset_yx / 8 + 1;
		  offset = yx23_err_code[i].offset_yx % 8-1;

		  // printf("tabid=%d  offset=%d\n",tabid,offset);
		  b1 = (plast_pf23[tabid] >> offset) & 0x01;
		  b2 = (pnew_pf23[tabid] >> offset) & 0x01;
		  // debug_mdata1("000发生故障  变化前=%d  变化后=%d  ",b1,b2);

		  if (b1 != b2)
		  {
			  if (b2 == 1)
			  {
				  debug_mdata("\r\n111发生故障 i:%d idx:%d errcode:0x%x", i, yx23_err_code[i].offset_yx, yx23_err_code[i].errCode);
                  err_code = yx23_err_code[i].errCode;
                  if ((err_code >= 0x3000) && (err_code < 0x5000))
                  {
                      // 桩故障，等待修复 
                	  charge_fault_upload(gunid + 1, err_code);
                  }
                  else if ((err_code >= 0x5000) && (err_code < 0x6000))
                  {
                      // 车辆故障 只上报故设置故障 
                	  charge_fault_upload(gunid + 1, err_code);
                  }
			  }
		  }
	  }
 
     return flag_err;
 }

 //20210619 add by cz
 u16 get_start_charge_error_code(u8 err_type_idx)
 {
     int  type_num = sizeof(start_charge_reason_map) / sizeof(failureReasonCode_t);
     int  i;
     u16  err_code = DEV_ERR_301D;
     //debug_mdata1("启动失败原因20210703 err_type_idx=0x%X ",err_type_idx);
     for (i = 0; i < type_num; i++)
     {
    	 if (err_type_idx == start_charge_reason_map[i].errReason)
         {
             err_code = start_charge_reason_map[i].errCode;
             //debug_mdata1("启动失败原因20210702 err_reason=0x%X err_code =0x%X ",start_charge_reason_map[i].errReason,start_charge_reason_map[i].errCode);
             break;
         }
     }

     return err_code;
 }
//add end

void  Finish_start_charge(u8 gunid)
{	
    printf("can充电完成！！！！！！！！！！！！！！！！！！！！！1\r\n");

    if(g_startInfo[gunid].MX2 == 0)
    {
        printf("can充电完成！！！！！！！！！！！！！！！！！！！！！2\r\n");
        debug_104("收到来自枪号%d的充电启动成功消息订单号=%s",gunid,g_chargepara_ql[gunid].serialnum);
        g_charge_state[gunid] = CHARGING;
        sprintf(_tmp_print_str," gunno=%d 启动充电成功 订单号=%s \n ",gunid,g_chargepara_ql[gunid].serialnum);
        gt_para_from_main.writelog(_tmp_print_str);
    }
    else if(g_startInfo[gunid].MX2==2)
    {
        sprintf(_tmp_print_str," gunno=%d 启动充电真正收到完成帧  订单号=%s \n ",gunid, g_chargepara_ql[gunid].serialnum);
        gt_para_from_main.writelog(_tmp_print_str);
        g_charge_state[gunid]=CHARGING;
    }
    else
    {
        g_charge_state[gunid]=NO_CHARGING;
        debug_104("收到来自枪号%d的充电启动失败消息 g_startInfo[gunid].MX3=%d",gunid,g_startInfo[gunid].MX3);
    }

    // 更新信息 
    user_update_bms_charging_by_start_MX(gunid + 1);
	if (g_startInfo[gunid].MX2 == 0)    // 设备操作成功
	{
		charge_operate_result[gunid][0] = 0;    // 执行结果
		charge_operate_result[gunid][1] = 0;    // 失败原因
	}
	else
	{
		charge_operate_result[gunid][0] = 1;    // 执行结果
		//20210624 add by cz
		charge_operate_result[gunid][1] = get_start_charge_error_code(g_startInfo[gunid].MX3 & 0xFF);    // 失败原因
	}
	debug_ql("mx2:%d mx3:%d, errcode:0x%x \r\n", g_startInfo[gunid].MX2, g_startInfo[gunid].MX3, charge_operate_result[gunid][1]);
	update_operate_result[gunid] = 1;   // 表示当前操作结束

    // debug_ql("枪号%d的充电启动成功  订单号=%s报告到平台\r\n", gunid, g_chargepara_ql[gunid].serialnum);
}

//20210619 add by cz
u16 get_stop_charge_error_code(end_mx *p_end)
{
    int  type_num = sizeof(stop_charge_reason_map) / sizeof(failureReasonCode_t);
    int  i;
    u16  err_code = CAR_ERR_5011;

    u8 err_type_idx = p_end->MX1 & 0xFF;

    for (i = 0; i < type_num; i++)
    {
    	//debug_mdata1("充电停止原因20210701 err_reason=%X err_code =%X ",stop_charge_reason_map[i].errReason,stop_charge_reason_map[i].errCode);
    	if (err_type_idx == stop_charge_reason_map[i].errReason)
        {
            err_code = stop_charge_reason_map[i].errCode;
            break;
        }
    }
    //20210625 add by cz
    if ((i >= type_num)||(err_type_idx == 0x2B))
    {
	    if ((p_end->dc.MX3 & 0xC0) == 0x40)
	    {
		   err_code = CAR_ERR_5036;  // 充电机中止
	    }
       	else if ((p_end->dc.MX4[0] & 0x03) == 0x01)
       	{
       		err_code = CAR_ERR_5031;
       	}
       	else if ((p_end->dc.MX4[0] & 0x0C) == 0x04)
		{
			err_code = CAR_ERR_5032;
		}
    	else if ((p_end->dc.MX4[0] & 0x30) == 0x10)
    	{
    	    err_code = CAR_ERR_5033;
    	}
    	else if ((p_end->dc.MX4[0] & 0xC0) == 0x40)
    	{
    	    err_code = CAR_ERR_5034;
    	}
    	else if ((p_end->dc.MX4[1] & 0x03) == 0x01)
    	{
    	    err_code = CAR_ERR_5035;
    	}
    	else if ((p_end->dc.MX4[1] & 0x0C) == 0x04)
    	{
    	    err_code = CAR_ERR_5038;
    	}
    	else if ((p_end->dc.MX4[1] & 0x30) == 0x10)
    	{
    		err_code = CAR_ERR_5037;
    	}
    	else if ((p_end->dc.MX4[1] & 0xC0) == 0x40)
    	{
    	    err_code = CAR_ERR_5036;
    	}
    	else if ((p_end->dc.MX5 & 0x03) == 0x01)
    	{
    	    err_code = CAR_ERR_5039;
    	}
    	else if ((p_end->dc.MX5 & 0x0C) == 0x04)
    	{
    	    err_code = CAR_ERR_503A;
    	}
    }

    return err_code;
}//add end

void Finish_stop_charge(u8 gunid,u8 flag)
{
	u16 err_code;
    u16 stop_reason = 5;
	t_operate_reason op_reason = {0};
    cmdlist  cmd;
	
    g_charge_state[gunid]=NO_CHARGING;
    if (flag==0)
        sprintf(_tmp_print_str,"gunno=%d收到停止完成的充电停止\n ",gunid);//409
    else
        sprintf(_tmp_print_str,"gunno=%d收到启动失败的充电停止\n ",gunid);

    user_update_bms_charging_by_end_MX(gunid + 1);

    gt_para_from_main.writelog(_tmp_print_str);

    if ((g_stopInfo[gunid].MX2 == 0)||(((g_stopInfo[gunid].MX2 == 1)&&((g_stopInfo[gunid].MX1 == 2)))))    // 设备操作成功 20210624 add by cz
	{
		charge_operate_result[gunid][0] = 0;    // 执行结果
		charge_operate_result[gunid][1] = get_stop_charge_error_code(&g_stopInfo[gunid]); // 失败原因
	}
	else
	{
		charge_operate_result[gunid][0] = 1;    // 执行结果
		charge_operate_result[gunid][1] = get_stop_charge_error_code(&g_stopInfo[gunid]);    // 失败原因
	}
	//update_operate_result[gunid] = 1;   // 表示当前操作结束
	//20210701 add
    if (update_operate_result[gunid] == 0) // TCU 调用停止充电，等待结果
    {
        update_operate_result[gunid] = 1;   // 接收到停止充电结果 
    }
    else
    {
        // 主动上报错误，TCU停止充电, CCU 主动停止 
        err_code = charge_operate_result[gunid][1];
        // 根据类型上报，有些是故障，
        if ((err_code >= 0x3000) && (err_code < 0x5000))
        {
            // 桩故障，等待修复 
            charge_fault_occur(gunid + 1, err_code);
			if (err_code == DEV_ERR_3003)
			{
				op_reason.reason = 7;
			}
            else if (err_code == DEV_ERR_3029)
			{
				op_reason.reason = 9;
			}
			else
		    {
				op_reason.reason = 5;
		    }
        }
        else if ((err_code >= 0x5000) && (err_code < 0x6000))
        {
            // 车辆故障 只上报故设置故障 
            charge_vehicle_fault_occur(gunid + 1, err_code);
			op_reason.reason = 6;
        }
		else if ((err_code >= 0x1000) && (err_code < 0x2000))
		{
			charge_vehicle_auto_stop_occur(gunid + 1, err_code); 
			op_reason.reason = get_stop_reason_by_fee(err_code);
		}
		else
		{
			op_reason.reason = 5;
		}
		
    	op_reason.gun_id = gunid;
		op_reason.detail_code = err_code;	// set detail stop reason by error code, 2021-07-09 zhouhao
		// 设置故障信息
		cmd.cmdtype = SET_STOP_DETAIL_REASON;
		cmd.body	= (void*)&op_reason;
		gt_para_from_main.cmd_fun(&cmd);
    }

    debug_ql("mx2:%d mx1:%d, errcode:0x%x \r\n", g_stopInfo[gunid].MX2, g_stopInfo[gunid].MX1, err_code);
	// debug_ql("枪号%d的停止充电成功  订单号=%s报告到平台\r\n", gunid, g_chargepara_ql[gunid].serialnum);
}

